#ifndef __IMP_MOVE_FILTER_H_
#define __IMP_MOVE_FILTER_H_

#ifdef __cplusplus
#if __cplusplus
extern "C"
{
#endif
#endif /* __cplusplus */

#include <imp/imp_common.h>
#include <imp_move_type.h>

static inline size_t alignSize(size_t sz, int n)
{
	assert((n & (n - 1)) == 0); // n is a power of 2
	return (sz + n-1) & -n;
}

static inline uint8_t* alignPtr(uint8_t* ptr, int n)
{
	return (uint8_t*)(((size_t)ptr + n-1) & -n);
}

typedef struct {
	int8_t* Rowmask;
	int8_t* Columnmask;
	int maskSize;
	int Rstep;
	int Cstep;
	int CntRoi;
	int County;
	int* Sum;
} MaskParamter;

typedef void (*RowFilterFunc)(const uint8_t* src, uint8_t* dst,int width, int cn,int ksize,int isUseSimd);

typedef int (*ColumnFilterFunc)(const uint8_t** src, uint8_t* dst, int dststep,int dstcount, int width,int ksize, MaskParamter* maskParamter, int isUseSimd);

typedef struct
{
	int* Noise_Thresh;
	MaskParamter maskParamter;
	int8_t* MaskData;

	zSize ksize;
	zPoint anchor;
	int maxWidth;
	zSize wholeSize;
	zRect roi;
	int dx1, dx2;
	uint8_t thresh_val;
	uint8_t max_val;
	int bufStep, startY, startY0, endY, rowCount, dstY;

	int borderTab[2];
	uint8_t* ringBuf;
	uint8_t* srcRow;
	uint8_t** rows;

	RowFilterFunc rowFilter;
	ColumnFilterFunc columnFilter;
}FilterEngine;

int MinsOp(const int a, const int b);
int MaxsOp(const int a, const int b);
uint8_t MinuOp(const uint8_t a, const uint8_t b);
uint8_t MaxuOp(const uint8_t a, const uint8_t b);

#if 0 //alisa
FilterEngine* Init(zSize Simg, int _ksize,int _anchor,uint8_t _thresh_val,uint8_t _max_val);
#else
FilterEngine* Init( zSize Simg, int _cntRoi, IMPRect* roiRect);
#endif

int Start(zSize wholeSize, zRect roi, int maxBufRows,FilterEngine* filter);

int Proceed(const uint8_t* src1, int src1Step,const uint8_t* src2, int src2Step,
		uint8_t* dst, int dstStep,FilterEngine* filter, int isUseSimd);

#if 0//alisa
int updateRoiMask(FilterEngine* filter, int width, int height, IMPRect* roi);
#else
int updateRoiMask(FilterEngine* filter, zRect srcRoi, IMPRect* roi);
#endif

void freeFilterEngine(FilterEngine* filter);

int remainingInputRows(FilterEngine* filter);

int remainingOutputRows(FilterEngine* filter);

void MorphRowFilter(const uint8_t* src, uint8_t* dst, int width, int cn,int ksize, int isUseSimd);
#if 0 //alisa
int MorphColumnFilter(const uint8_t** _src, uint8_t* dst, int dststep, int count, int width,int ksize, int isUseSimd);
#else
int MorphColumnFilter(const uint8_t** _src, uint8_t* dst, int dststep, int count, int width,int ksize, MaskParamter* maskParamter, int isUseSimd);
#endif

Image CreateImage(void* src, int width,int height,int type);

#if 0 //alisa
int move_detect(Image src1,Image src2,Image dst,int* rets,FilterEngine* filterEngine,int isUseSimd,IMPRect* rois,int cntRoi);
#else
int move_detect(Image src1,Image src2,Image dst,int* rets,FilterEngine* filterEngine, int isUseSimd);
#endif

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* __cplusplus */
#endif
